package com.yst.suivi.services;

import java.rmi.RemoteException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.ejb.EJBException;
import javax.ejb.SessionContext;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

import org.apache.commons.lang.StringUtils;

import com.yst.suivi.services.exceptions.BusinessErrorCode;
import com.yst.suivi.services.exceptions.BusinessException;

public abstract class AbstractSessionBean
{
	public static final String DB_JNDI_NAME = "java:/suivi";

	protected static final int SIMPlE_FIELD_MAX_LENGTH = 250;

	protected static final int VERSION_FIELD_MAX_LENGTH = 25;

	private SessionContext context = null;

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.ejb.SessionBean#ejbActivate()
	 */
	public void ejbActivate() throws EJBException, RemoteException
	{
		// by default nothing to do
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.ejb.SessionBean#ejbPassivate()
	 */
	public void ejbPassivate() throws EJBException, RemoteException
	{
		context = null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.ejb.SessionBean#ejbRemove()
	 */
	public void ejbRemove() throws EJBException, RemoteException
	{
		// by default nothing to do
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.ejb.SessionBean#setSessionContext(javax.ejb.SessionContext)
	 */
	public void setSessionContext(SessionContext arg0) throws EJBException, RemoteException
	{
		context = arg0;
	}

	/**
	 * Method checks if a String is empty. If it is then a BusinessException is
	 * raised with the given parameter.
	 * 
	 * @param fieldValue
	 * @param errorParamters
	 */
	protected void checkEmptyField(String fieldValue, String[] errorParamters)
	{
		if (StringUtils.isEmpty(fieldValue))
		{
			throw new BusinessException(BusinessErrorCode.EMPTY_FIELD, errorParamters);
		}
	}

	/**
	 * The method checks the length of the value. If it is too long a
	 * BusinessException is raised. The error parameter is the name of the
	 * field.
	 * 
	 * @param fieldValue
	 * @param length
	 * @param errorParameters
	 */
	protected void checkFieldLength(String fieldValue, int length, String name)
	{
		if (null != fieldValue)
		{
			String[] errorParameters = new String[2];
			errorParameters[0] = name;
			errorParameters[1] = Integer.toString(length);
			if (fieldValue.length() > length)
			{
				throw new BusinessException(BusinessErrorCode.FIELD_TOO_LONG, errorParameters);
			}
		}
	}

	/**
	 * The methode checks if the field value is already used in the system. The
	 * check is made on a object and for a field.
	 * 
	 * @param fieldValue
	 * @param table
	 * @param field
	 * @param id
	 */
	protected void checkUnicity(String fieldValue, String table, String field, String id)
	{
		checkUnicity(fieldValue, table, field, id, "");
	}

	/**
	 * The methode checks if the field value is already used in the system. The
	 * check is made on a object and for a field. A where clause could be set if
	 * necessary.
	 * 
	 * @param fieldValue
	 * @param table
	 * @param field
	 * @param criterion
	 */
	protected void checkUnicity(String fieldValue, String table, String field, String id, String criterion)
	{
		Connection conn = null;
		ResultSet rs = null;
		PreparedStatement ps = null;
		try
		{
			String[] errorParametersTransaled = new String[1];
			errorParametersTransaled[0] = field;
			String[] errorParametersNotTransaled = new String[1];
			errorParametersNotTransaled[0] = fieldValue;
			InitialContext ctx = new InitialContext();
			DataSource ds = (DataSource) ctx.lookup(DB_JNDI_NAME);
			conn = ds.getConnection();
			StringBuffer request = new StringBuffer();
			request.append("select count(*) FROM ");
			request.append(table);
			request.append(" WHERE ").append(field).append(" = '").append(fieldValue).append("'");
			request.append(" AND id!='").append(id).append("'").append(criterion);
			ps = conn.prepareStatement(request.toString());
			// execute the request
			rs = ps.executeQuery();
			// checks the result of the request. If it is not 0 raised an error.
			rs.next();
			if (0 != rs.getInt(1))
			{
				throw new BusinessException(BusinessErrorCode.FIELD_ALREADY_EXISTS, errorParametersTransaled, errorParametersNotTransaled);
			}
		}
		catch (NamingException e)
		{
			throw new RuntimeException(e);
		}
		catch (SQLException e)
		{
			throw new RuntimeException(e);
		}
		finally
		{
			if (null != ps)
			{
				try
				{
					ps.close();
				}
				catch (SQLException e)
				{
					throw new RuntimeException(e);
				}
			}
			if (null != rs)
			{
				try
				{
					rs.close();
				}
				catch (SQLException e)
				{
					throw new RuntimeException(e);
				}
			}
			if (null != conn)
			{

				try
				{
					conn.close();
				}
				catch (SQLException e)
				{
					throw new RuntimeException(e);
				}
			}
		}
	}

	/**
	 * @return Returns the context.
	 */
	protected SessionContext getContext()
	{
		return context;
	}
}
